#ifndef _OPENGLAPPFRAMEWORK_LIGHTSOURCE_H_
#define _OPENGLAPPFRAMEWORK_LIGHTSOURCE_H_

#include "OpenglAppFramework/inc/glm/glm.hpp"
#include "OpenglAppFramework/inc/Shader.h"
#include "OpenglAppFramework/inc/PlugIn/Camera.h"
#include "OpenglAppFramework/inc/PlugIn/PlugIn.h"
#include "OpenglAppFramework/inc/Texture.h"
#include <string>

enum class LightSourceType {
    Parallel, Spot, Point
};

class LightSource : public PlugIn{
public:
    std::string name;

    LightSource(const std::string& name, LightSourceType type);
    ~LightSource();
    
    void uploadShaderData(Shader* s);
    void uploadShadowShaderData(Shader* s);
    void enableShadow(bool is_enable);
    void setDirectionNormalized(const glm::vec3& direction);
    bool isShadowEnabled() const;
    int init();
    virtual int shadowShaderInit();
    void destroy();
    const glm::vec3& location() const;
    uint32_t getFrameBufferId() const;
    uint32_t getShadowTextureId() const;

    Shader* getShadowShader();
    unsigned int getShadowTextureId();

protected:
    glm::vec3 m_ambient;
    glm::vec3 m_diffuse;
    glm::vec3 m_specular;
    glm::vec3 m_direction;
    LightSourceType m_light_type;
    float m_half_angle;
    // 光源的location使用GameObject的location

    bool m_is_shadow_enabled;
    Shader m_shadow_shader;
    Camera m_scam;

    uint32_t m_shadow_fbo_id;
    uint32_t m_shadow_tex_id;
};

class ParallelLightSource : public LightSource {
public:
    ParallelLightSource(const std::string& name);
    ~ParallelLightSource();

    int setConfigData(const nlohmann::json& data) override;
    int shadowShaderInit() override;
    void routine() override;
};

#endif//_OPENGLAPPFRAMEWORK_LIGHTSOURCE_H_
